定期ミートアップ 第42回
Shiika キーワード引数
code:sk
class A
def foo(a: Int, b: Int, c: Int, d: Int)
...
end
def bar
foo(1,2,3,4)
foo(1,2,c: 3, d: 4)
foo(1,2,d: 4, c: 3)
foo(c: 3, d: 4, 1, 2) # エラー
end
Shiika デフォルト引数
実装中
code:sk
class A
def foo(a: Int = 123)
...
end
...
A.new.foo() # foo(123) と同じ
どうやるか?
a) ASTレベルでコピーする?
code:sk
class A
def foo(a: Int = x) # これはエラーにしたい
...
def foo(a: Int = A.xxx) # 存在しないメソッドなのでエラー
def foo(a: Int = 123.to_s) # 型エラー
b) HIRレベルでコピーする?
メソッド呼び出しをHIRにコンパイルするときに、省略された式をコピーして埋め込む
code:sk
foo()
↓書き換え
foo(3)
→タイミングが難しい
現在の処理
トラバース1 各クラスの型パラメータを拾う
トラバース2 各メソッドのシグネチャを集める
トラバース3 各メソッドの本体をコンパイルする
どのタイミングでやればよいか
実はどれもだめ
2でやるとすると
code:sk
class A
def foo(a: Int = A.bar()) # ここではまだbarのことを知らない
...
end
def bar -> Int
...
3でやるとすると
code:sk
class A
def foo
bar() # 式をコピーしたいがまだ作られていない
end
def bar(a: Int = A.baz())
2と3の間に追加するかなあ
c) codegenでなんとかする?
HirDefaultExpr
ミートアップ終わったあとに気づいたんだけど、HIRをコピーする方式だとRustやCからShiiikaメソッドを呼び出すケースに対応できないわ。やはり呼び出される側に判定を入れるのが良さそう
code:sk
class A
def foo(a: Int = A.bar)
↓
def foo(a_: Maybe<Int> = Some.new(A.bar))
let a =
----
以下、メモ帳
code:sk
class A
def foo(a: Int = if; let b = 1; b; else; 2; end)) # これはなしにしたい、、
class A
def foo(a: Int = 3)
↓
def foo(a_: Maybe<Int> = Some.new(3))
let a = if a_ == None
3
else
// LLVM
func @A_foo(%Int* a) {
aがnullptrなら aに3を入れる
...
}
class A
def foo(a: Int, *args: Array<Int>)
foo(1, 2, 3)
↓書き換え
foo(1, *ary)
↓書き換え
foo(1, ary)
class A
def bar(a: Int, b: String)
bar(*ary)